package cn.g31010.sip.util;


import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.config.ObjectClass;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 *
 * @author qingfeng.gao
 */
public class DB {

    private static ObjectContainer db;
    private static boolean autoCommit = false;
    private String file;
    private static Map<String, DB> dbs = new Hashtable<String, DB>();
    private boolean open;

    private DB(String file) {
        this.file = file;
    }

    public static DB getDB(String file) {
        if (!dbs.containsKey(file)) {
            DB db = new DB(file);
            db.open();
            dbs.put(file, db);
        }
        return dbs.get(file);
    }
    
    public static DB getDB(String file,Class c,String[] index){
        if (!dbs.containsKey(file)) {
            DB db = new DB(file);
            db.open(c,index);
            dbs.put(file, db);
        }
        return dbs.get(file);
    }

    public void add(Object o) {
        db.store(o);
        if (autoCommit) {
            db.commit();
        }
    }

    public void delete(Object o) {
        db.delete(o);
        if (autoCommit) {
            db.commit();
        }
    }
    
    public void deactivate(Object o,int depth){
        db.deactivate(o, depth);
        if (autoCommit) {
            db.commit();
        }
    }

    public boolean isOpen() {
        return open;
    }

    public synchronized void open() {
        try {
            System.setProperty("db4o.dynamicnq", "true");
            System.out.println("open database......");
            db = Db4o.openFile(file);
            open = true;
            System.out.println("open database......OK");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void open(Class c,String[] index) {
        try {
            System.setProperty("db4o.dynamicnq", "true");
            ObjectClass classConfig = Db4o.configure().objectClass(c);
            for(int i=0;i<index.length;i++){
                classConfig.objectField(index[i]).indexed(true);
            }
            System.out.println("open database......");
            db = Db4o.openFile(file);
            open = true;
            System.out.println("open database......OK");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void close() {
        System.out.println("close database......");
        db.close();
        open = false;
        System.out.println("close database......OK");
    }

    public synchronized void commit() {
        db.commit();
    }

    public List query(Predicate filter) {
        List filtered = db.query(filter);
        return filtered;
    }
    
    public ObjectSet find(Predicate filter) {
        return db.query(filter);
    }
    
    public List query(Class c) {
        Query query = db.query();
        query.constrain(c);
        ObjectSet result = query.execute();
        return toList(result);
    }
    
    public ObjectSet find(Class c) {
        Query query = db.query();
        query.constrain(c);
        ObjectSet result = query.execute();
        return result;
    }

    public void update(Object o) {
        db.store(o);
        if (autoCommit) {
            db.commit();
        }
    }

    private List toList(ObjectSet set) {
        List l = new ArrayList();
        for (Iterator iter = set.iterator(); iter.hasNext();) {
            l.add(iter.next());
        }
        return l;
    }

    public void setAutoCommit(boolean flag) {
        autoCommit = flag;
    }

    
    }
